package com.virgo.demo.core.aspectj;

import com.virgo.common.entity.IUserToken;
import com.virgo.common.exception.IApplicationException;
import com.virgo.demo.core.annotation.Log;
import com.virgo.demo.support.domain.bo.OperationLogBo;
import com.virgo.demo.support.service.OperationLogService;
import com.virgo.demo.support.service.SystemRightCheckService;
import com.virgo.login.service.TokenService;
import com.virgo.web.utils.IRequestUtils;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;

@Aspect
@Component
@RequiredArgsConstructor
public class LogAspect {

	private final TokenService tokenService;

	private final OperationLogService operationLogService;

	private final SystemRightCheckService systemRightCheckService;

	/**
	 * 处理请求前执行
	 */
	@Before(value = "@annotation(controllerLog)")
	public void boBefore(JoinPoint joinPoint, Log controllerLog)
	{
		if (!ObjectUtils.isEmpty(controllerLog.permission())) {
			//查询权限
			IUserToken iUserToken = tokenService.get(true);
			Boolean res = systemRightCheckService.checkAdminRight(iUserToken.getUserId(), iUserToken.getRoleId(), controllerLog.permission());
			if (!res) {
				throw new IApplicationException("无权操作");
			}
 		}
	}

	/**
	 * 处理完请求后执行
	 * @param joinPoint 切点
	 */
	@AfterReturning(pointcut = "@annotation(controllerLog)", returning = "jsonResult")
	public void doAfterReturning(JoinPoint joinPoint, Log controllerLog, Object jsonResult)
	{
		handleLog(joinPoint, controllerLog, null, jsonResult);
	}

	/**
	 * 拦截异常操作
	 * @param joinPoint 切点
	 * @param e 异常
	 */
	@AfterThrowing(value = "@annotation(controllerLog)", throwing = "e")
	public void doAfterThrowing(JoinPoint joinPoint, Log controllerLog, Exception e)
	{
		handleLog(joinPoint, controllerLog, e, null);
	}

	protected void handleLog(final JoinPoint joinPoint, Log controllerLog, final Exception e, Object jsonResult)
	{
		if (controllerLog.saveLog()) {
			IUserToken iUserToken = tokenService.get(true);
			OperationLogBo operationLogBo = new OperationLogBo();
			operationLogBo.setUserId(iUserToken.getUserId());
			operationLogBo.setModule(controllerLog.module());
			operationLogBo.setOperType(controllerLog.type());
			HttpServletRequest httpServletRequest = IRequestUtils.getHttpServletRequest();
			operationLogBo.setIp(IRequestUtils.getIpAddr(httpServletRequest));
			operationLogBo.setUserAgent(httpServletRequest.getHeader("User-Agent"));
			operationLogService.saveLog(operationLogBo);
		}
	}

}